# ifndef GECOMMND_H
# define GECOMMND_H
# include "stdIn.hh"
# include "files.hh"
# include <cstring>
# include <string>
# include <unistd.h>
# include <cstdio>
# include <iostream>
# include <cstdlib>
# include <pwd.h>

std::string getCommand(void);
void cursLeft(int & cursor, std::string com);
void cursRight(int & cursor, std::string com);
void lastOneCmd(int & cursor, std::string & com,int & number);
void nextOneCmd(int & cursor, std::string & com,int & number);




std::string getCommand(void)
{
    std::string com="", showcom; // com 真正执行的命令, showcom 展示到用户的命令
    int cursor; //光标索引    
    int number=1;//第几次按方向上键
    char temp, temp1;
    
    std::system("stty -echo");
    std::system("stty -icanon");
    cursor = com.length();
    std::cout<< "\033[s";
    std::fflush(stdout);
    while(true)
    {
        temp = getchar();
        // std::system("clear");
        if (temp == 10)
        {
            std::system("stty echo");
            std::system("stty icanon");
            putchar(10);
            // // std::cout<< std::endl<<com<< std::endl;

            return com;
        }
        else if (temp == 27 and (getchar() == '['))
        {
            temp1 = getchar();
            // std::cout<<temp1<<std::endl<<std::endl;
            switch (temp1) /*判断光标位置以及光标移动.*/
            {
                case 'A':
                    number++;
                    std::cout<<"\033["<<cursor<<"D";
                    std::cout << "\033[K";
                    lastOneCmd(cursor, com, number);
                    break;
                case 'B':
                    number--;
                    std::cout<<"\033["<<cursor<<"D";
                    std::cout << "\033[K";
                    nextOneCmd(cursor, com, number);
                    break;
                case 'C': 
                cursRight(cursor,  com);break;
                case 'D': 
                cursLeft(cursor,  com);break;
                case 'H':
                cursor = 0;break;
                case 'F':
                cursor = showcom.length()-1;break;
                case '3':
                if (getchar()=='~')
                {
                    com.erase(cursor, 1);break;
                }
                default:
                break;
            }

        }
        else
        {
            // insertChar(cursor, com, showcom, temp);
            /*在光标的位置, 把字符塞进去*/
            switch(temp)
            {
                case 127: 
                if (cursor-1>=0)
                {
                    com.erase(cursor-1, 1); cursor--; break;
                }
                else
                {
                    break;
                }
                default:com.insert(cursor, 1, temp);cursor++;break;
            }
            // com.insert(cursor, 1, temp);
            // cursor ++;
        }
        
        //std::cout<<"成到"<<std::endl;
        std::fflush(stdout);
        std::cout << "\r";
        showcom = com+" ";

        std::cout << "\033[u\033[k" << showcom << "\033[u"; //恢复光标位置, 清除光标之后的所有内容
                                                                // 把命令插进去, 恢复光标位置
        std::fflush(stdout);
        // std::cout<<cursor<<std::endl;
        // << std::endl << com.length()<<std::endl
        if (cursor > 0)
        {
        std::cout<<"\033["<<cursor<<"C";
        }
        
    }
    std::system("stty echo");
    
    std::system("stty icanon");
    // return "OK";

}


void cursRight(int & cursor, std::string com)
{
    /*光标即将移动,所以先保留光标目前的位置的值*/
    cursor = cursor>=com.length()?cursor:cursor+1;

}
void cursLeft(int & cursor, std::string com)
{
    /*光标即将移动,所以先保留光标目前的位置的值*/
    cursor = cursor==0?cursor:cursor-1;

}

void lastOneCmd(int & cursor, std::string & com, int & number)
{
//    char tmpbdpc[5012];
//    getcwd(tmpbdpc, sizeof(tmpbdpc));
//    static std::string __BuildPlace(tmpbdpc);

    passwd* pwd;
    pwd = getpwuid(getuid());
    std::string userName = pwd->pw_name;

    std::cout << "\033[u\033[k";
    // std::cout << "\033[K";
    std::string path = "/home/" + userName + "/.data/dems/histCommand/hist.dms";
    std::string lastcmd=getLineOFile(path,"end",number);
    lastcmd.erase(0, lastcmd.find_first_not_of(" "));
    lastcmd.erase(lastcmd.find_last_not_of(" ")+1);
    lastcmd.erase(lastcmd.find_last_not_of("\n")+1);
    // std::cout<<"上条指令是:"<<lastcmd<<std::endl;
    // 将这个值赋给com和showcom, 
    com=lastcmd;
    // 并且将cursor的值定位到末尾
    cursor=com.length();
    // std::cout << "此时的com是" << com << "ok" << std::endl;
}

void nextOneCmd(int & cursor, std::string & com, int & number)
{
//    char tmpbdpc[5012];
//    getcwd(tmpbdpc, sizeof(tmpbdpc));
//    static std::string __BuildPlace(tmpbdpc);
    passwd* pwd;
    pwd = getpwuid(getuid());
    std::string userName = pwd->pw_name;

    std::cout << "\033[u\033[k";
    std::string path = "/home/" + userName + "/.data/dems/histCommand/hist.dms";
    std::string nextcmd=getLineOFile(path,"end",number);
    nextcmd.erase(0, nextcmd.find_first_not_of(" "));
    nextcmd.erase(nextcmd.find_last_not_of(" ")+1);
    nextcmd.erase(nextcmd.find_last_not_of("\n")+1);
    // 将这个值赋给com和showcom, 
    com=nextcmd;
    // 并且将cursor的值定位到末尾
    cursor=com.length();
}
# endif